
#if 1

#include <iostream>

using namespace std;

//不使用库函数，实现strcmp、strcpy、strstr的功能

/**
    1. 对于strcmp函数
        同步递增，找到两个字符串中，第一个不同的字符。
        判断连个字符的大小

        注意：该函数的设计，主要在于列举所有情况
        1. 能找到不同的字符
            str1>str2 ==return 1
            str2<str2 == return -1
        2. 不能找到不同的字符
            1） 字符串1结束了，字符串2没有结束，字符串2> 字符串1，return -1
            2） 字符串2结束了，字符串1没有结束，字符串1> 字符串2 ，return 1
            3） 字符串1和字符串2都结束了，说明两个字符串一样，return 0

*/

int c_strcmp(const char * str1,const char * str2) //使用指针常量，保证在函数内不修改字符串的值
{
    //参数合法性检查
    if(str1==NULL||str2==NULL)
    {
        cout<<"参数非法"<<endl;
        exit(0);
    }

    //找不同的字符
    while(*str1!='\0' && *str2!='\0' && *str1==*str2)
    {
        str1++;
        str2++;
    }

    //找不同的字符可能出现下面的情况
    //1. str1结束，str2没有结束
    if(*str1=='\0' && *str2!='\0')
    {
        return -1;
    }
    //2. str1没结束，但是str2结束了
    else if(*str1!='\0' && *str2=='\0')
    {
        return 1;
    }
    //3. str1和str2都没有结束
    else if(*str1!='\0' && *str2!='\0')
    {
        if(*str1>*str2)
        {
            return 1;
        }else
        {
            return -1;
        }
    }else
    {
        return 0;
    }
}

/**
    2. 对于strcpy函数
        需要一块空间，用来存储拷贝过来的字符串
        char str1[] ==> 空间

        //返回值是str1
*/
char * c_strcpy(char * str1,const char * str2) //const 保证函数不会修改str2
{
    //指针指向数组
    char *p = str1; //str1是数组，不能执行++操作
    //参数合法性检查
    if(p==NULL || str2 == NULL)
    {
        cout<<"参数错误"<<endl;
        exit(0);
    }

    //拷贝
    while(*str2!='\0')
    {
        *p = *str2;
        p++;
        str2++;
    }
    *p = '\0';
    return str1;
}

/**
    实现strstr函数，查找子串
        找到str1中和子串第一个字母相同的地方，顺序比较，一直比较到*str2='\0'
        如何找相同的地方，str1挨个字母和str2的首字母比较
        返回的是指向匹配字符串的位置指针

*/

char * c_strstr(const char * str1,const char * str2) //不修改str1和str2
{
    char * src,* sub; //由于要返回的是子串首次出现的首部位置，如果直接用str1++的话，就变成尾部位置了。
    //参数检查
    if(str1==NULL || str2==NULL)
    {
        cout<<"参数不合法"<<endl;
        exit(0);
    }

    while(*str1!='\0')
    {
        src = const_cast<char*>(str1);  //cosnt char * 赋值给char *会出错，通过const_cast类型转换
        sub = const_cast<char *>(str2);
        //找相同的地方
        while(*src != *sub)
        {
            src++;
            str1++;
        }
        //从相同的位置开始顺序比较
        while(*sub==*src)
        {
            sub++;
            src++;
            if(*sub=='\0')
            {
                return const_cast<char *>(str1);
            }
        }
        //如果子串还没结束，就不匹配了，那么就从下一位重新开始比较。
        str1++;

    }
    return NULL; //没有找到
}

int main()
{

    cout<<"c_strcmp:"<<c_strcmp("helloworld","hellooworld")<<endl; //1
    char str1[11];
    char * str2 = "helloworld";
    cout<<"c_strcpy:"<<c_strcpy(str1,str2)<<endl;
    char *str3 = "helloworld";
    char *str4 = "world";
    cout<<"c_strstr:"<<c_strstr(str3,str4)<<endl;
	system("pause");
	return 0;
}
#endif
